#include "main.h"
extern int fd;
extern struct Env recv;
extern pthread_mutex_t mutex1;
extern pthread_mutex_t mutex2;
extern pthread_cond_t cond;
extern int flag;
extern que_head *qh;

void serial_init(int fd)
{
	struct termios options;
	tcgetattr(fd, &options);
	options.c_cflag |= ( CLOCAL | CREAD );
	options.c_cflag &= ~CSIZE;
	options.c_cflag &= ~CRTSCTS;
	options.c_cflag |= CS8;
	options.c_cflag &= ~CSTOPB; 
	options.c_iflag |= IGNPAR;
	options.c_iflag &= ~(ICRNL | IXON);
	options.c_oflag = 0;
	options.c_lflag = 0;

	cfsetispeed(&options, B115200);
	cfsetospeed(&options, B115200);
	tcsetattr(fd,TCSANOW,&options);
}
void *zig_read(void *date){
	int ret;
	struct Env data={};
	while(1){
		ret=0;
		bzero(&data,sizeof(data));
		ret=read(fd,&recv,sizeof(recv));
		if(ret<0){
			perror("read");
		}
		else{
			//入栈、解锁
			que_insert(qh,data);
			pthread_mutex_unlock(&mutex1);
	}}
}
void * pick(void *date){
	int ret;
	while(1){
		pthread_mutex_lock(&mutex1);
		pthread_mutex_lock(&mutex2);
		while(flag!=1){
			pthread_cond_wait(&cond,&mutex2);
		}
		ret=0;
		bzero(&recv,sizeof(recv));
		que_read(qh,recv);
		ret=suit();
		pthread_mutex_unlock(&mutex2);
		switch (ret){
		case 1:
			flag=1;break;
		case 2:
			flag=2;break;
		case 3:
			flag=3;break;
		}
		pthread_cond_broadcast(&cond);
	}

}
//分析数据
int suit(){
	int rec;
	char *p=(char*)&recv;
	rec=strncmp("st:",p,3);
	if(rec!=0)
		return 1;
	else{
		if(p[3]==0)
			return 2;
		else
			return 3;
	}
}
//数据库操作
void * sqlite_back(void *date)
{
	int ret;
	char buf[512]="";
	char *p=(char*)&recv;
	sqlite3* pdb=NULL;
	ret=sqlite3_open("./date.db",&pdb);
	if(ret!=0){
		perror("sqlite3_open");
	}
	sprintf(buf,"create table if not exists cargo(io int ,goodsno int,goodsnum int );");
	sqlite3_exec(pdb,buf,NULL,NULL,NULL);
	while(1){
		pthread_mutex_lock(&mutex2);
		while(flag!=2){
			pthread_cond_wait(&cond,&mutex2);
		}
		pthread_mutex_unlock(&mutex2);
		bzero(buf,512);
		sprintf(buf,"insert into cargo values (%d,%d,%d);",p[5],p[6],p[7]);
		sqlite3_exec(pdb,buf,NULL,NULL,NULL);
		flag=1;
		pthread_cond_broadcast(&cond);
	}
}

//信号灯集解锁
int sem_p(int semid, int num)
{
	struct sembuf mybuf;
	mybuf.sem_num = num;
	mybuf.sem_op  = -1;
	mybuf.sem_flg = SEM_UNDO;
	if(semop(semid, &mybuf, 1) < 0){
		perror("semop");
		exit(1);
	}

	return 0;
}

//信号灯集上锁
int sem_v(int semid, int num)
{
	struct sembuf mybuf;
	mybuf.sem_num = num;
	mybuf.sem_op  = 1;
	mybuf.sem_flg = SEM_UNDO;
	if(semop(semid, &mybuf, 1) < 0){
		perror("semop");
		exit(1);
	}

	return 0;
}

float to_float(uint8_t n[])
{
	int temp = 0;

	printf("%#x\n", n[1]);
	uint8_t temper = n[1];
	float num;
	float sum = 0;

	while(1){
		num = temper % 10;
		temper /= 10;
		if(num == 0){
			temp++;
			if(temp == 2) break;
		}
		sum = sum / 10.0 + num;
	}
	sum = sum + n[0];

	printf("sum: %g\n", sum);
	return sum;
}

//共享内存
void *shrmem_back(void *date)
{
	float n;

	key_t key;
	int shmid,semid;
	struct shm_addr *shm_buf = NULL;

	if((key = ftok("/app", 'i')) < 0){
		perror("ftok");
		exit(1);
	}

	if((semid = semget(key, 1, IPC_CREAT|0666)) < 0){
		perror("semget");
		exit(1);
	}

	if((shmid = shmget(key, 32, IPC_CREAT|0666)) == -1){
		perror("shmget");
		exit(1);
	}

	if((shm_buf = (struct shm_addr*)shmat(shmid, NULL, 0)) == (void *)-1){
		perror("shmat");
		exit(1);
	}

	while(1){
		sem_v(semid, 0);

		shm_buf->rt_status.storage_no[1].storage_status = 1;
		shm_buf->rt_status.storage_no[1].temperature    = to_float(recv.temp);
		shm_buf->rt_status.storage_no[1].humidity       = to_float(recv.hum);
		shm_buf->rt_status.storage_no[1].illumination   = (float)recv.ill;
		shm_buf->rt_status.storage_no[1].battery 	    = (float)recv.bet;
		shm_buf->rt_status.storage_no[1].adc 		    = (float)recv.adc;
		shm_buf->rt_status.storage_no[1].x 				= recv.x;
		shm_buf->rt_status.storage_no[1].y 				= recv.y;
		shm_buf->rt_status.storage_no[1].z 				= recv.z;
#if 0
		shm_buf->rt_status.storage_no[1].temperatureMIN  = (float)thld->temperature_min;
		shm_buf->rt_status.storage_no[1].temperatureMAX  = (float)thld->temperature_max;
		shm_buf->rt_status.storage_no[1].humidityMIN     = (float)thld->humidity_min;
		shm_buf->rt_status.storage_no[1].humidityMAX     = (float)thld->humidity_max;
		shm_buf->rt_status.storage_no[1].illuminationMIN = (float)thld->light_min;
		shm_buf->rt_status.storage_no[1].illuminationMAX = (float)thld->light_max;
#endif
		sem_p(semid, 0);
	}
}
